/**
 *------------------------------------
 * /lib/Socket.js
 * @author ayuanlmo
 * Create by ayuanlmo in 2021/06/30
 * ------------------------------------
 * **/
let Socket = null;//套接字容器
let timingSocketPush = null;//套接字push定时器（发送心跳）
let onMessageCallback = null;

export const createSocket = url => {
    Socket && Socket.close();
    if (!Socket) {
        console.log('开始建立Socket连接...');
        Socket = new WebSocket(`${url}`);//跟Socket建立连接
        Socket.onopen = openSocket;//onopen代表连接
        Socket.onmessage = SocketOnMessage;//onmessage发送消息
        Socket.onerror = SocketOnError;//onerror连接错误时执行的方法
        Socket.onclose = SocketOnClose;//onclose断开连接时执行的方法
    } else {
        console.log('Socket已连接...');
    }
}
//连接成功
const openSocket = ()=>{
    sendPing();//开始发送心跳包
}
//收到消息
const SocketOnMessage = (e)=>{
    if(e.data !== 'pong'){
        if(typeof onMessageCallback === 'function'){
            onMessageCallback(JSON.parse(e.data));
        }
    }
}

export const setOnMessageCallback = func=>{
    if(typeof func === 'function'){
        onMessageCallback = func;
    }else{
        return null;
    }
}
//连接失败
const SocketOnError = ()=>{
    Socket.close();
    clearInterval(timingSocketPush);
    console.log('Socket失败重连中...');
    if(Socket.readyState !== 3){
        Socket = null;
        createSocket();
    }
}

//发送数据，但未取得套接字链接（等待发送）
const awaitMessageSend = msg=>{
    setTimeout(()=>{
        if(Socket.readyState === 0){
            awaitMessageSend(msg);
        }else{
            Socket.send(anyToString(msg));
        }
    })
}
//断开重连
const SocketOnClose = ()=>{
    clearInterval(timingSocketPush);//删除定时器
    console.log('Socket连接断开，尝试重连中...');
    if(Socket.readyState !== 2){
        Socket = null;
        createSocket();
    }
}

//发送心跳包
export const sendPing = (duration = 30000, str = 'ping')=>{
    clearInterval(timingSocketPush);
    Socket.send(anyToString(str));
    timingSocketPush = setInterval(()=>{
        Socket.send(anyToString(str));
    },duration)
}
//推送消息
export const pushMessage = (msg,userName)=>{
    if(Socket !== null && Socket.readyState === 3){//等于3代表连接已经关闭或没有连接成功
        Socket.close();
        createSocket();
    }else if(Socket.readyState === 1){//Socket.readyState等于1时代表连接成功可以进行正常通信
        Socket.send(anyToString(msg));
    }else if(Socket.readyState === 0){//等于0代表正在连接肿
        awaitMessageSend(msg)
    }
}
//将any数据转换为string
const anyToString = str=>{
    if(typeof str === 'undefined'){
        return '';
    }else if(typeof str === 'object'){
        return JSON.stringify(str);
    }else if(typeof str === 'boolean' || typeof str === 'number' || typeof str === 'string'){
        return `${str}`
    }else{
        return str;
    }
}
